package com.DataProcess;

import android.util.Log;

import java.util.Arrays;

/**
 * Created by tjpu on 2016/10/12.
 */
public class CanDataDecode {
    private String thisLogTag = "CanDataDecode";

    private byte[] data ={0,0,0,0, 0,0,0,0};
    public String type = CanDataType.FAIL;
    //sensors data
    public short[] speed = {0,0};
    public int uwbID1 = 0;
    public short uwbDistance1 = 0;
    public int uwbID2 = 0;
    public short uwbDistance2 = 0;
    public short [] ird = {0,0,0,0, 0,0,0,0};
    public short [] drop = {0,0};
    public short[] plate = {0,0};
    public short batterySurplus = 0;
    public short batteryVoltage = 0;
    public short [] gyroscope = {0,0,0};
    public short [] acceleration = {0,0,0};
    public boolean chargeStatus = false;


    public byte[] getData() {
        byte [] data = new byte[this.data.length];
        System.arraycopy(this.data,0,data,0,data.length);

        return data;
    }

    public void decode(byte[] data) {
        if (data != null) {
            this.data = data;
            notReceiveCnt = 0;
            isNotReceive = false;
            Log.i(thisLogTag,"data to decode:"+ Arrays.toString(data));
            switch (data[0]) {
                case 0x00:
                    break;
                case 0x01:
                    speedsDecode();
                    break;
                case 0x03:
                    uwbDecode();
                    break;
                case 0x04:
                case 0x05:
                    irdDecode();
                    break;
                case 0x06:
                    dropDecode();
                    break;
                case 0x07:
                    plateDecode();
                    break;
                case 0x09:
                    batteryDecode();
                    break;
                case 0x0b:
                    break;
                case 0x0d:
                    chargeDecode();
                    break;
                case 0x10:
                    gyroscopeDecode();
                    break;
                case 0x11:
                    accelerationDecode();
                    break;
                default:
                    type = CanDataType.FAIL;
                    Log.i(thisLogTag,"wrong data to decode:"+ Arrays.toString(data));
            }
        }
    }

    void speedsDecode() {
        speed[0] = (short)(( (data[1]&0x00ff) << 8) |  (data[2]&0x00ff) );
        speed[1] = (short)(( (data[3]&0x00ff) << 8) |  (data[4]&0x00ff) );
        type = CanDataType.SPEED;
        Log.i(thisLogTag,"speed:"+Arrays.toString(speed));
    }

    void uwbDecode() {
        uwbID1 = (short) ((data[1] & 0x00ff));
        uwbDistance1 = (short) (((data[2] & 0x00ff) << 8) | (data[3] & 0x00ff));
        uwbID2 = (short) ((data[4] & 0x00ff));
        uwbDistance2 = (short) (((data[5] & 0x00ff) << 8) | (data[6] & 0x00ff));
        type = CanDataType.UWB;
        Log.i(thisLogTag,"uwb"+uwbID1+":"+uwbDistance1+"uwb2:"+uwbID2+":"+uwbDistance2);
    }

    void irdDecode(){
        int i;
        if (data[0] == 0x04) {
            i = 0;
        } else {
            i = 4;
        }
        for(int j=0;j<4;j++) {
            ird[i] = (short)(data[j+1] & 0x00ff);
            i++;
        }
        type = CanDataType.IRD;
        Log.i(thisLogTag,"ird:"+Arrays.toString(ird));
    }

    void dropDecode() {
        drop[0] = (short)(data[1] & 0x00ff);
        drop[1] = (short)(data[2] & 0x00ff);
        type = CanDataType.DROP;
        Log.i(thisLogTag,"drop:"+Arrays.toString(drop));
    }

    void plateDecode() {
        plate[0] = (short) (((data[1] & 0x00ff) << 8) | (data[2] & 0x00ff));
        plate[1] = (short) (((data[3] & 0x00ff) << 8) | (data[4] & 0x00ff));
        type = CanDataType.PLATE;
        Log.i(thisLogTag,"plate:"+Arrays.toString(plate));
    }

    void batteryDecode() {
        batterySurplus = (short)(data[1] & 0x00ff);
        batteryVoltage = (short)(data[2] & 0x00ff);
        type = CanDataType.BATTERY;
        Log.i(thisLogTag,"batterSurplus:"+batterySurplus+"  batterVoltage:"+batteryVoltage);
    }

    void chargeDecode() {
        if(data[1] > 0x00) chargeStatus = true;
        else chargeStatus = false;
        type = CanDataType.CHARGE;
        Log.i(thisLogTag,"chargeStatus:"+chargeStatus);
    }

    void gyroscopeDecode() {
        gyroscope[0] = (short) (((data[1] & 0x00ff) << 8) | (data[2] & 0x00ff));
        gyroscope[1] = (short) (((data[3] & 0x00ff) << 8) | (data[4] & 0x00ff));
        gyroscope[2] = (short) (((data[5] & 0x00ff) << 8) | (data[6] & 0x00ff));
        type = CanDataType.GYRO;
        Log.i(thisLogTag,"gyroscope:"+Arrays.toString(gyroscope));
    }

    void accelerationDecode() {
        acceleration[0] = (short) (((data[1] & 0x00ff) << 8) | (data[2] & 0x00ff));
        acceleration[1] = (short) (((data[3] & 0x00ff) << 8) | (data[4] & 0x00ff));
        acceleration[2] = (short) (((data[5] & 0x00ff) << 8) | (data[6] & 0x00ff));
        Log.i(thisLogTag,"acceleration:"+Arrays.toString(acceleration));
    }

    public int notReceiveCnt = 0;
    public boolean isNotReceive = false;
    public void checkReceive() {
        notReceiveCnt++;  //在dataFromCan()里面清零
        notReceiveCnt ++;
        if (notReceiveCnt > 3) {
            isNotReceive = true;
            Log.e(thisLogTag,"CAN didn't receive data in "+notReceiveCnt+ "times");
        }
        if(notReceiveCnt > 10)
            notReceiveCnt = 10;
    }
}
